package com.hm.health.Activity.ecgflash;

import static com.hm.health.Activity.ecgflash.EcgFlashDetailActivity.EXT_ECG_PATCH_CSV_ID;
import static com.hm.health.Activity.ecgflash.EcgFlashDetailActivity.EXT_ECG_PATCH_CSV_TIME;
import static com.hm.health.Activity.ecgflash.EcgFlashDetailActivity.EXT_ECG_PATCH_TEST_RECORD_ID;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.RecyclerView;

import com.goodix.RxProgressDialog.RxProgressSubscribe;
import com.goodix.activity.FileBrowserActivity;
import com.goodix.utils.TimeUtil;
import com.goodix.utils.ToastUtils;
import com.hm.health.Activity.BaseActivity;
import com.hm.health.R;
import com.hm.health.adapter.EcgFlashExportAdapter;
import com.hm.health.records.ecgpatch.EcgPatchRecordReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

public class EcgFlashExportToPdfActivity extends BaseActivity {
    public static final String EXT_ECG_FLASH_RECORD_NUM = "EXT_ECG_FLASH_RECORD_NUM";
    public static final String EXT_ECG_FLASH_PATH = "EXT_ECG_FLASH_PATH";
    public static final String EXT_ECG_FLASH_DAY_STR = "EXT_ECG_FLASH_DAY_STR";
    public static final String EXT_ECG_FLASH_TIME_STR = "EXT_ECG_FLASH_TIME_STR";

    public static final String TAG = "ExportEcgToPdfActivity";

    private static final int REQUEST_CODE = 1;

    @BindView(R.id.rl_pdf_view)
    NestedScrollView mRlPdfView;
    @BindView(R.id.rv_chart_view)
    RecyclerView mRvRecycleView;
    @BindView(R.id.tv_record_time)
    TextView mTvRecordTime;
    @BindView(R.id.tv_name)
    TextView mTvName;
    @BindView(R.id.tv_hr_average)
    TextView mTvHrAverage;
    @BindView(R.id.tv_pathological_information)
    TextView mTvPathologicalInformation;

    private EcgPatchRecordReader.CurrentHourData mCurrentHourData;
    private EcgFlashExportAdapter mEcgFlashExportAdapter;
    private MyHandler mHandler = new MyHandler(Looper.myLooper(),this);

    private String mPath;

    static class MyHandler extends Handler{
        WeakReference<EcgFlashExportToPdfActivity> mActivity;

        public MyHandler(@NonNull Looper looper, EcgFlashExportToPdfActivity activity){
            super(looper);
            mActivity = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            EcgFlashExportToPdfActivity activity = mActivity.get();
            if (activity == null)
                return ;

            switch (msg.what) {
                case 1:
                    mActivity.get().saveViewToPDF();
                    break;
                default:
                    break;
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_export_ecgflash_to_pdf);
        ButterKnife.bind(this);

        initActionBar(getString(R.string.export_ecg_chart));
        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mEcgFlashExportAdapter = new EcgFlashExportAdapter(this);
        loadEcgData();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) {
            return;
        }

        if (requestCode == REQUEST_CODE) {
            setCenterTitle(getString(R.string.wait_for_pdf_export));
            mPath = data.getStringExtra(FileBrowserActivity.EXTRA_KEY_PATH);
            mHandler.sendEmptyMessage(1);
        }
    }

    private void loadEcgData() {
        Observable.create((Observable.OnSubscribe<EcgPatchRecordReader.CurrentHourData>) subscriber -> {
            String testRecordId = getIntent().getStringExtra(EXT_ECG_PATCH_TEST_RECORD_ID);
            int testCsvId = getIntent().getIntExtra(EXT_ECG_PATCH_CSV_ID, 0);
            long startTime = getIntent().getLongExtra(EXT_ECG_PATCH_CSV_TIME, 0l);
            EcgPatchRecordReader.CurrentHourData data = EcgPatchRecordReader.getInstance().loadDataList(testRecordId, testCsvId, startTime);
            mEcgFlashExportAdapter.updateData(data);
            subscriber.onNext(data);
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            subscriber.onCompleted();
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new RxProgressSubscribe<>(getString(R.string.ecg_flash_data_loading),
                        new Observer<EcgPatchRecordReader.CurrentHourData>() {
                            @Override
                            public void onCompleted() {
                                mRvRecycleView.setHasFixedSize(true);
                                mRvRecycleView.setNestedScrollingEnabled(false);
                                mRvRecycleView.setItemViewCacheSize(60);
                                RecyclerView.RecycledViewPool recycledViewPool = new RecyclerView.RecycledViewPool();
                                mRvRecycleView.setRecycledViewPool(recycledViewPool);
                                mRvRecycleView.setAdapter(mEcgFlashExportAdapter);
                                mEcgFlashExportAdapter.notifyDataSetChanged();

                                Date date = new Date(mCurrentHourData.mStartTimestamp);
                                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
                                mTvRecordTime.setText(format.format(date));
                                mTvName.setText(mCurrentHourData.mName + "-" +mCurrentHourData.mScene);

                                // 心率均值
                                mTvHrAverage.setText(String.format(getString(R.string.hr_average_format), mCurrentHourData.mHrv));

                                // 节律信息
                                mTvPathologicalInformation.setText("xxxx");
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(EcgPatchRecordReader.CurrentHourData currentHourData) {
                                mCurrentHourData = currentHourData;
                            }
                        }, mContext));
    }

    protected void initActionBar(String title) {
        ActionBar actionBar = getSupportActionBar();
        actionBar.setHomeButtonEnabled(true);
        setCenterTitle(title);
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.ecg_save, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.ecg_save:
                String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                FileBrowserActivity.startBrowser(EcgFlashExportToPdfActivity.this,
                        REQUEST_CODE, true, "", path);
                break;
            case R.id.home:
                finish();
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    private void saveViewToPDF() {
        String time = TimeUtil.formateTime(mCurrentHourData.mStartTimestamp);
        String name = String.format("ecg-chart-%s-%s-%s.pdf", mCurrentHourData.mName, mCurrentHourData.mScene, time);

        List<Bitmap> bitmaps = takescreenshotOfNested(mRlPdfView);

        Observable.create((Observable.OnSubscribe<String>) subscriber -> {
            // create a new document
            PdfDocument document = new PdfDocument();

            int pageWidth = mRlPdfView.getWidth();
            int pageHeight = mRlPdfView.getHeight();

            int bitmapIndex = 0;
            for (int bitmapY=0; bitmapIndex<bitmaps.size();) {
                PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(
                        pageWidth, pageHeight, 1).create();
                PdfDocument.Page page = document.startPage(pageInfo);
                Canvas canvas = page.getCanvas();

                for (int pageY=0; pageY < pageHeight;) {
                    if (bitmapIndex >= bitmaps.size()) {
                        break;
                    }
                    Bitmap bitmap = bitmaps.get(bitmapIndex);

                    int bitmapWidth = bitmap.getWidth();
                    int bitmapHeight = bitmap.getHeight();
                    int bitmapRemainHeight = bitmapHeight - bitmapY;
                    int pageX = (pageWidth - bitmapWidth) / 2;

                    if (pageY + bitmapRemainHeight < pageHeight) {
                        // page remain
                        Rect dst = new Rect(pageX, pageY, pageWidth, pageY + bitmapRemainHeight);
                        Rect src = new Rect(0, bitmapY, pageWidth, (bitmapY + bitmapRemainHeight));
                        canvas.drawBitmap(bitmap, src, dst, null);

                        pageY += bitmapRemainHeight;
                        bitmapY = 0;
                        bitmapIndex++;

                        //bitmap.recycle();
                    } else if (pageY + bitmapRemainHeight == pageHeight) {
                        // page and bitmap remain same
                        Rect dst = new Rect(pageX, pageY, pageWidth, pageHeight);
                        Rect src = new Rect(0, bitmapY, pageWidth, bitmapY + bitmapRemainHeight);
                        canvas.drawBitmap(bitmap, src, dst, null);

                        bitmapY = 0;
                        bitmapIndex++;

                        break;
                    } else {
                        // bitmap remain
                        // TODO: can put to next page if (bitmapHeight < pageHeight)

                        Rect dst = new Rect(pageX, pageY, pageWidth, pageHeight);
                        Rect src = new Rect(0, bitmapY, pageWidth, bitmapY + (pageHeight - pageY));
                        canvas.drawBitmap(bitmap, src, dst, null);

                        bitmapY += (pageHeight - pageY);
                        //pageY = 0;
                        break;
                    }
                }

                document.finishPage(page);
            }

            File file = new File(mPath, name);
            FileOutputStream outputStream = null;
            try {
                outputStream = new FileOutputStream(file);
                document.writeTo(outputStream);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                document.close();
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            subscriber.onCompleted();
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new RxProgressSubscribe<>(getString(R.string.wait_for_pdf_save),
                        new Observer<String>() {
                            @Override
                            public void onCompleted() {
                                ToastUtils.showShortToastMessage(EcgFlashExportToPdfActivity.this, getString(R.string.pdf_save_success));
                                setCenterTitle(getString(R.string.export_ecg_chart));
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(String data) {
                            }
                        }, mContext));

    }

    private List<Bitmap> takescreenshotOfNested(NestedScrollView u) {
        NestedScrollView viewNested = u;

        List<Bitmap> bitmaps = new ArrayList<>();

        if (viewNested != null) {
            viewNested.setDrawingCacheEnabled(false);
            viewNested.invalidate();
            viewNested.getChildAt(0).setDrawingCacheEnabled(false);
            viewNested.getChildAt(0).invalidate();

            // ecg items
            LinearLayout linearLayout = (LinearLayout) viewNested.getChildAt(0);
            RelativeLayout relativeLayout = (RelativeLayout) linearLayout.getChildAt(0);
            RecyclerView recyclerView = (RecyclerView) linearLayout.getChildAt(linearLayout.getChildCount() - 1);

            // head elements
            Bitmap bitmap = Bitmap.createBitmap(relativeLayout.getWidth(),
                    relativeLayout.getHeight() + 8, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            relativeLayout.draw(canvas);
            bitmaps.add(bitmap);

            Log.d(TAG, "recyclerView count " + recyclerView.getChildCount());

            // foreach recycler view
            for (int i=0, j=recyclerView.getChildCount(); i<j; i++) {
                View view = recyclerView.getChildAt(i);

                bitmap = Bitmap.createBitmap(view.getWidth(),
                        view.getHeight() + 8, Bitmap.Config.ARGB_8888);
                canvas = new Canvas(bitmap);
                view.draw(canvas);
                bitmaps.add(bitmap);
            }
        } else {
            return null;
        }

        return bitmaps;
    }
}